package com.shrct.businessprocess.customerservice.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.customerservice.RCRoutineService;
import com.shrct.businessprocess.customerservice.RCRoutineServiceItem;
import com.shrct.businessprocess.customerservice.RCServiceContractDelegate;
import com.shrct.businessprocess.customerservice.impl.RCRoutineServiceItemImpl;
import com.shrct.businessprocess.customerservice.impl.RCServiceContractDelegateImpl;
import com.shrct.businessprocess.customerservice.proxy.RCRoutineServiceProxy;
import com.shrct.businessprocess.product.RCLogicProduct;
import com.shrct.businessprocess.product.impl.RCLogicProductImpl;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.IntegerRange;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCROUTINESERVICE_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcroutineservice")
public class RCRoutineServiceImpl extends BaseModelObject implements RCRoutineService {
  public RCRoutineServiceImpl() {
    super();
  }
  
  private String groupName;
  
  public String getGroupName() {
    return this.groupName;
  }
  
  public RCRoutineService setGroupName(final String groupName) {
    this.groupName = groupName;
    return this;			
    
  }
  
  @JoinColumn(name = "projectInfo_id")
  @ManyToOne(targetEntity = RCServiceContractDelegateImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCServiceContractDelegate projectInfo;
  
  public RCServiceContractDelegate getProjectInfo() {
    return this.projectInfo;
  }
  
  public RCRoutineService setProjectInfo(final RCServiceContractDelegate projectInfo) {
    this.projectInfo = projectInfo;
    return this;			
    
  }
  
  @ManyToMany(targetEntity = RCLogicProductImpl.class)
  @JoinTable(name = "m2m_rcroutineservice_products", joinColumns = @JoinColumn(name = "rcroutineservice_id") , inverseJoinColumns = @JoinColumn(name = "rCLogicProduct_inv_id") )
  private Collection<RCLogicProduct> products = new java.util.ArrayList<com.shrct.businessprocess.product.RCLogicProduct>();;
  
  public Collection<RCLogicProduct> getProducts() {
    return this.products;
  }
  
  public RCRoutineService setProducts(final Iterable<RCLogicProduct> products) {
    removeAllProducts();
    for(RCLogicProduct ca : products){
    	addtoProducts(ca);
    }
    return this;		
    
  }
  
  public RCRoutineService addtoProducts(final RCLogicProduct rCLogicProduct) {
    this.products.add(rCLogicProduct);
    return this;
    
  }
  
  public RCRoutineService removeAllProducts() {
    this.products.clear();
    return this;	
    
  }
  
  public RCRoutineService removeFromProducts(final RCLogicProduct rCLogicProduct) {
    this.products.remove(rCLogicProduct);
    return this;
    
  }
  
  private String installLocation;
  
  public String getInstallLocation() {
    return this.installLocation;
  }
  
  public RCRoutineService setInstallLocation(final String installLocation) {
    this.installLocation = installLocation;
    return this;			
    
  }
  
  private Date routineStartDate;
  
  public Date getRoutineStartDate() {
    return this.routineStartDate;
  }
  
  public RCRoutineService setRoutineStartDate(final Date routineStartDate) {
    this.routineStartDate = routineStartDate;
    return this;			
    
  }
  
  private Date routineEndDate;
  
  public Date getRoutineEndDate() {
    return this.routineEndDate;
  }
  
  public RCRoutineService setRoutineEndDate(final Date routineEndDate) {
    this.routineEndDate = routineEndDate;
    return this;			
    
  }
  
  private Integer serviceInterval;
  
  public Integer getServiceInterval() {
    return this.serviceInterval;
  }
  
  public RCRoutineService setServiceInterval(final Integer serviceInterval) {
    this.serviceInterval = serviceInterval;
    return this;			
    
  }
  
  private Integer planCount;
  
  public Integer getPlanCount() {
    return this.planCount;
  }
  
  public RCRoutineService setPlanCount(final Integer planCount) {
    this.planCount = planCount;
    return this;			
    
  }
  
  private Integer finishedCount = Integer.valueOf(0);
  
  public Integer getFinishedCount() {
    return this.finishedCount;
  }
  
  public RCRoutineService setFinishedCount(final Integer finishedCount) {
    this.finishedCount = finishedCount;
    return this;			
    
  }
  
  private Boolean isFinished = Boolean.valueOf(false);
  
  public Boolean getIsFinished() {
    return this.isFinished;
  }
  
  public RCRoutineService setIsFinished(final Boolean isFinished) {
    this.isFinished = isFinished;
    return this;			
    
  }
  
  public Integer getServiceDuration() {
    Long _between = DateUtil.between(this.routineStartDate, this.routineEndDate);
    int _intValue = _between.intValue();
    return Integer.valueOf(_intValue);
  }
  
  public Iterable<RCLogicProduct> getRelatedProducts() {
    return this.products;
  }
  
  @OneToMany(targetEntity = RCRoutineServiceItemImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "rountineService")
  private Collection<RCRoutineServiceItem> remenders = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCRoutineServiceItem>();;
  
  public Collection<RCRoutineServiceItem> getRemenders() {
    return this.remenders;
  }
  
  public RCRoutineServiceItem createAndAddtoRemenders() {
    getRemenders().size();
    com.shrct.businessprocess.customerservice.RCRoutineServiceItem rCRoutineServiceItem = new com.shrct.businessprocess.customerservice.impl.RCRoutineServiceItemImpl(this);
    getObjectFactory().create(rCRoutineServiceItem);
    getRemenders().add(rCRoutineServiceItem);
    return rCRoutineServiceItem;
    
  }
  
  public RCRoutineServiceItem createAndAddtoRemenders(final Procedure1<RCRoutineServiceItem> updater) {
    getRemenders().size();
    com.shrct.businessprocess.customerservice.RCRoutineServiceItem rCRoutineServiceItem = new com.shrct.businessprocess.customerservice.impl.RCRoutineServiceItemImpl(this);
    getObjectFactory().create(rCRoutineServiceItem);
    getRemenders().add(rCRoutineServiceItem);
    return rCRoutineServiceItem;
    
  }
  
  public RCRoutineService removeAllRemenders() {
    for(RCRoutineServiceItem obj : this.remenders){
    	getObjectFactory().delete(obj);
    }
    this.remenders.clear();
    return this;	
    
  }
  
  public RCRoutineService removeFromRemenders(final RCRoutineServiceItem rCRoutineServiceItem) {
    this.remenders.remove(rCRoutineServiceItem);
    getObjectFactory().delete(rCRoutineServiceItem);
    return this;
    
  }
  
  public RCRoutineService update(final Procedure1<? super RCRoutineService> preInit) {
    RCRoutineServiceImpl _xblockexpression = null;
    {
      preInit.apply(this);
      Integer _serviceDuration = this.getServiceDuration();
      int _divide = ((_serviceDuration).intValue() / (this.serviceInterval).intValue());
      this.planCount = Integer.valueOf(_divide);
      this.removeAllRemenders();
      this.generateRemenders();
      _xblockexpression = (this);
    }
    return _xblockexpression;
  }
  
  public void generateRemenders() {
    IntegerRange _upTo = new IntegerRange(1, (this.planCount).intValue());
    final Procedure1<Integer> _function = new Procedure1<Integer>() {
        public void apply(final Integer index) {
          RCRoutineServiceItem _createAndAddtoRemenders = RCRoutineServiceImpl.this.createAndAddtoRemenders();
          final Procedure1<RCRoutineServiceItem> _function = new Procedure1<RCRoutineServiceItem>() {
              public void apply(final RCRoutineServiceItem it) {
                int _multiply = ((index).intValue() * (RCRoutineServiceImpl.this.serviceInterval).intValue());
                Date _addDays = DateUtil.addDays(RCRoutineServiceImpl.this.routineStartDate, _multiply);
                it.setPlanDate(_addDays);
              }
            };
          ObjectExtensions.<RCRoutineServiceItem>operator_doubleArrow(_createAndAddtoRemenders, _function);
        }
      };
    IterableExtensions.<Integer>forEach(_upTo, _function);
  }
  
  public void finishedOnce() {
    int _plus = ((this.finishedCount).intValue() + 1);
    this.finishedCount = Integer.valueOf(_plus);
    boolean _equals = Objects.equal(this.finishedCount, this.planCount);
    if (_equals) {
      this.isFinished = Boolean.valueOf(true);
    }
  }
  
  public static RCRoutineService create(final IObjectFactory objectFactory) {
    com.shrct.businessprocess.customerservice.RCRoutineService rCRoutineService = new com.shrct.businessprocess.customerservice.impl.RCRoutineServiceImpl(
    );
    objectFactory.create(rCRoutineService);
    return rCRoutineService;			
    
  }
  
  public static RCRoutineService createRCRoutineServiceImpl(final IObjectFactory objectFactory, final Procedure1<RCRoutineService> init) {
    com.shrct.businessprocess.customerservice.RCRoutineService rCRoutineService = new com.shrct.businessprocess.customerservice.impl.RCRoutineServiceImpl(
    );
    objectFactory.create(rCRoutineService);
    init.apply(rCRoutineService);
    
    return rCRoutineService;			
    
  }
  
  public RCRoutineServiceProxy toProxy() {
    com.shrct.businessprocess.customerservice.proxy.RCRoutineServiceProxy proxy = new com.shrct.businessprocess.customerservice.proxy.RCRoutineServiceProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
